package com.ss.security;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

import com.ss.bean.Resource;
import com.ss.bean.Role;

/**
 * 资源源数据定义，即定义某一资源可以被哪些角色访问。可预先加载全局资源，缓存起来。 此类在初始化时，应该取到所有资源及其对应角色的定义， 获取单个资源所需权限，
 * 匹配资源的规则，匹配顺序
 * 
 * @author Robin
 */

@Component("securityMetadataSource")
public class MyInvocationSecurityMetadataSource extends HibernateDaoSupport
        implements FilterInvocationSecurityMetadataSource {
	@Autowired(required=true)
    public void init(SessionFactory sessionFactory) {
        super.setSessionFactory(sessionFactory);
        loadResourceDefine();
    }
	
	private PathMatcher urlMatcher = new AntPathMatcher();
    private static Map<String, Collection<ConfigAttribute>> resourceMap = null;

    public MyInvocationSecurityMetadataSource() {
         
     }

    public void loadResourceDefine() {
		List<Resource> urlResources = getHibernateTemplate().find(
				"FROM Resource r WHERE r.type = ? order by id desc", "URL");//注意匹配的顺序，以某种顺序取出url
    	
		resourceMap = new LinkedHashMap<String, Collection<ConfigAttribute>>();

		for (Resource resource : urlResources) {
			String reourceVal = resource.getValue();
			for (Role role : resource.getRoles()) {
				String roleName = role.getName();
				
				ConfigAttribute ca = new SecurityConfig(roleName);
				
				if (!resourceMap.containsKey(reourceVal)) {
					resourceMap.put(reourceVal, new ArrayList<ConfigAttribute>());
				}
				resourceMap.get(reourceVal).add(ca);
			}
		}
     }

    // According to a URL, Find out permission configuration of this URL.
    public Collection<ConfigAttribute> getAttributes(Object object)
            throws IllegalArgumentException {
        // guess object is a URL.
         String url = ((FilterInvocation)object).getRequestUrl();
         Iterator<String> ite = resourceMap.keySet().iterator();
        while (ite.hasNext()) {
             String resURL = ite.next();
            if (urlMatcher.match(resURL, url)) {
                return resourceMap.get(resURL);
             }
         }
        return null;
     }

    public boolean supports(Class<?> clazz) {
        return true;
     }
    
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
     }

    public static void main(String[] args) {
    	int a = 0;
    	System.out.println(new MyInvocationSecurityMetadataSource().urlMatcher.match("/**", "/index.jsp"));
    }
}
